#!/usr/bin/python

# Authors:  
# Otavio Sturm 
# Vinicius Arcanjo 

import math
import numpy
import random
import matplotlib.pyplot as plt

###### FUNCTIONS #######

def generateNoisyVector(mean, amplitude, samples):
	
	auxVec = []

	for i in range(0,samples):

		# (random.random()*2)-1 => it generates a number which belongs to [-1,1]
		# amplitude/2.0 => maximum peak/valley value
		# mean behaves like an offset	
		auxVec.append(mean + ((random.random()*2)-1)*amplitude/2.0)			
	
	return auxVec


def correlation(firstVec, secondVec):

	# corrrelationVec size
	finalVec = numpy.zeros((len(firstVec) + len(secondVec))-1)

	# secondVec reversed for sliding through firstVec
	secondVecReverse = list(secondVec)
	secondVecReverse.reverse()

	# zero padding
	slidingVec = [0] * len(firstVec)
	
	# zero padding
	for i in range(0,len(firstVec)-1):
		secondVecReverse.append(0)

	########################
	# CORRELATION DEFINITION
	# finalVec[i] = SUM(slidingVec[i+k]*firstVec[k]), i => 0 to 2*len(slidingVec)-1.
	########################

	for i in range(0,len(finalVec)):

		sum = 0
		slidingVec.insert(0,secondVecReverse[i])
		slidingVec.pop()

		for k in range(0,len(firstVec)):
			sum  += slidingVec[k]*firstVec[k]								
			#print "slidingVeck", slidingVec[k], "firstVeck", firstVec[k]
		#print			
		finalVec[i] = sum

	return finalVec

def calculateSignalNoiseRatio(signalAmp, noiseAmp):

	return 20*math.log10(signalAmp/noiseAmp)


def plotModulationBitVector(bitOneSignal, bitZeroSignal):

	plt.figure(2)
	plt.subplot(211)
	plt.title('bitOneSignal')
	plt.plot(bitOneSignal)

	plt.subplot(212)
	plt.title('bitZeroSignal')
	plt.plot(bitZeroSignal)
	#plt.show()

def plotVectorNoisyCorrelation(resVec, bitOneSignal, bitZeroSignal, signalAmp, noiseAmp):

	labelStr = "Sinal + Ruido Amp=" + str(noiseAmp) + " S/N Ratio=" + str(calculateSignalNoiseRatio(signalAmp,noiseAmp))

	plt.figure(1)
	plt.subplot(311)
	plt.title(labelStr)
	plt.plot(resVec)

	plt.subplot(312)
	plt.title('Correlacao(Sinal+Ruido,bitOneSignal)')
	plt.plot(correlation(resVec,bitOneSignal))

	plt.subplot(313)
	plt.title('Correlacao(Signal+Ruido,bitZeroSignal)')
	plt.plot(correlation(resVec,bitZeroSignal))
	#plt.show()

############### MAIN FLOW EXECUTION #####################

def main():

############## FIXED PARAMETERS ########################

	# noise parameters
	noiseMean = 10
	noiseAmplitude = 1000.0
	samples = 400

	# auxiliaries signal to represent a coded bit 0 or 1.
	bitSignalSamples = 200
	bitSignalAmplitude = 50.0

	# Init - lists
	signalVec = [0] * samples 
	resVec = [0] * samples

	bitOneSignal = [0] * bitSignalSamples
	bitZeroSignal = [0] * bitSignalSamples

	# Generate bitOne|ZeroSignal according to the set parameters

	for i in range(50,150):
		bitOneSignal[i] = (bitSignalAmplitude/2.0)*math.sin(math.radians(3.6*(i-50)))
		bitZeroSignal[i] = bitOneSignal[i]*-1

	signalVec = bitOneSignal + bitZeroSignal 


	################ END FIXED PARAMETERS ####################

	################ DYNAMIC PARAMETERS ######################

	######################################## 
	# noisyVec 
	########################################

	noisyVec = generateNoisyVector(noiseMean,noiseAmplitude,samples)

	for i in range(0,len(resVec)):
		resVec[i] = signalVec[i] + noisyVec[i]

	plotVectorNoisyCorrelation(resVec, bitOneSignal, bitZeroSignal, bitSignalAmplitude, noiseAmplitude)

	plotModulationBitVector(bitOneSignal, bitZeroSignal)

	plt.show()
	
